/*
 * Created on 2008-06-06
 *
 * To change the template for this generated file go to
 * Window&gt;Preferences&gt;Java&gt;Code Generation&gt;Code and Comments
 */
package elka.isi.operator;

import elka.isi.individual.AnimalIndividual;
import elka.isi.util.RWUtils;
import org.evolvica.core.IIndividualSet;
import org.evolvica.util.RandomUtils;

import java.util.Arrays;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

/**
 * @author jurek
 * 
 * To change the template for this generated type comment go to
 * Window&gt;Preferences&gt;Java&gt;Code Generation&gt;Code and Comments
 */
public class HarvestingEcosystem extends SortedEcosystem {

	private int carrotAvailable;

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.evolvica.core.population.IPopulation#insert(org.evolvica.core.IIndividualSet)
	 */
	public IIndividualSet insert(IIndividualSet iset) {

		// putting herbivores into sorted population

		List herbivores = Arrays.asList(RWUtils.getHerbivores(iset).toArray());
		Collections.sort(herbivores, comparator);

		int rabbits = RWUtils.getRabbits(iset).size();
		int roes = RWUtils.getRoes(iset).size();

		int rabbitsToAll = 1 + (rabbits + roes) / (rabbits + 1);
		int roesToAll = 1 + (rabbits + roes) / (roes + 1);

		int carrotEaten = 0;

		for (Iterator iterator = herbivores.iterator(); iterator.hasNext() ;) {
			AnimalIndividual individual = (AnimalIndividual) iterator.next();

			double appetite = 0;
			double howManyCarrotsToEat = 0;
			int throwNumber = 0;
			switch (individual.getSpecies()) {
				case AnimalIndividual.RABBIT :

					throwNumber = 0;
					howManyCarrotsToEat = 0;
					for (int j = 0; j < rabbitsToAll; j++) {
						throwNumber = RandomUtils.randomInt(7);
						if (throwNumber < 3)
						{
							appetite = ((AnimalIndividual) individual).getAppetiteScore();
							howManyCarrotsToEat = appetite;
							carrotEaten += (int) howManyCarrotsToEat;
							break;
						} else
						{
							continue;
						}
					}
					if ( howManyCarrotsToEat == 0) iset.remove(individual);
					
					break;
					
				case AnimalIndividual.ROE :

				throwNumber = 0;
				howManyCarrotsToEat = 0;
				for (int j = 0; j < roesToAll; j++) {
					throwNumber = RandomUtils.randomInt(7);
					if (throwNumber < 3)
					{
						appetite = ((AnimalIndividual) individual).getAppetiteScore();
						howManyCarrotsToEat = appetite;
						carrotEaten += (int) howManyCarrotsToEat;
						break;
					} else
					{
						continue;
					}
				}
				if ( howManyCarrotsToEat == 0) 
				{
		//			System.out.println("HERB DEAD IN HARV");
					iset.remove(individual);
				}
					
					break;
				default :
					throw new IllegalStateException("Niepoprawny gatunek.");
			}

			if (carrotEaten > carrotAvailable) 
			{
   				
   				switch (individual.getSpecies()) {
   				case AnimalIndividual.RABBIT:
   					iset.remove(individual);
   					break;
   				case AnimalIndividual.ROE:
   					iset.remove(individual);
   					break;
   				case AnimalIndividual.WOLF:
   					throw new IllegalStateException(
   						"Jakis syf, wilki zaczely zrec marchewke! ;)");
   				default:
   					break;
   				}
   			}
		}


		//			
		//			if (carrotEaten < carrotAvailable) {
		//				double appetite = ((AnimalIndividual) individual)
		//						.getAppetiteScore();
		//
		//				/*
		//				 * appetiteScore = size * size * muscle / metabolism
		//				 * 
		//				 * size, muscle i metabolism sa losowane z przedzialu 1 do 100,
		//				 * wiec apetite score waha sie w graniacach od ok 1 do 10 000 -
		//				 * w zwiazku z tym, znormalizujmy ilosc marchewki zjadanej w tym
		//				 * przedziale: min. ilosc zjadanej marchewki 1, maksymalna 11
		//				 * (zaokraglenie do gory)
		//				 */
		//				
		////				TODO: nie prosciej ewaluowac ilosc marchewki do zjedzenia
		////				jako obliczona wartosc apetite (ktora powinna byc typu int, sensowna)?
		////				/Zibi
		//				//double howManyCarrotsToEat = appetite / 10 + 1;
		//                double howManyCarrotsToEat = appetite;
		//
		//
		//                carrotEaten += (int) howManyCarrotsToEat;
		//				herbivoresFeeded++;
		//			} else {
		//				
		//				switch (individual.getSpecies()) {
		//				case AnimalIndividual.RABBIT:
		//					iset.remove(individual);
		//					break;
		//				case AnimalIndividual.ROE:
		//					iset.remove(individual);
		//					break;
		//				case AnimalIndividual.WOLF:
		//					throw new IllegalStateException(
		//						"Jakis syf, wilki zaczely zrec marchewke! ;)");
		//				default:
		//					break;
		//				}
		//			}
		//		}
		return iset;
	}

	public void setCarrotAvailable(int i) {
		carrotAvailable = i;
	}

}
